# !/usr/bin/env python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
    File Name：    path_manger.py
    Description:   企业级路径管理工具类
-------------------------------------------------
"""

from pathlib import Path
from functools import lru_cache
import logging
import os
from dotenv import load_dotenv

# 加载环境变量
load_dotenv()

# 初始化日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# 模块公开接口
__all__ = ["paths", "config_manager"]


class PathManager:
    """
    路径管理类，包含企业项目中的各种路径常量。
    """

    # 获取项目的根目录，可以通过环境变量覆盖
    BASE_DIR = Path(os.getenv('PROJECT_BASE_DIR', Path(__file__).resolve().parent.parent))

    # 数据目录
    DATA_DIR = BASE_DIR / 'data'
    TEST_DATA_DIR = DATA_DIR / 'test_datas'

    # 测试用例目录
    TEST_CASE_DIR = BASE_DIR / 'src' / 'tests' / 'test_cases'

    # 源代码和测试目录
    SRC_DIR = BASE_DIR / 'src'
    TESTS_DIR = SRC_DIR / 'tests'

    # 配置文件目录和路径
    CONFIG_DIR = BASE_DIR / 'config'
    CONFIG_TOML_PATH = CONFIG_DIR / os.getenv('CONFIG_FILE_TOML', 'dev.toml')
    CONFIG_YAML_PATH = CONFIG_DIR / os.getenv('CONFIG_FILE_YAML', 'config.yaml')

    # 日志和报告目录
    LOGS_DIR = BASE_DIR / 'logs'
    REPORT_DIR = BASE_DIR / 'report'
    HTML_REPORT_DIR = REPORT_DIR / 'html'  # html报告文件夹
    ALLURE_RESULTS_DIR = REPORT_DIR / 'allure-results'  # allure结果文件夹
    ALLURE_REPORT_DIR = REPORT_DIR / 'allure-report'  # allure报告文件夹

    @classmethod
    def ensure_directory_exists(cls) -> None:
        """
        确保所有定义的目录存在，不存在则创建
        """
        for name, path in cls.list_all_paths().items():
            if not path.exists():
                try:
                    logger.info(f"目录不存在，创建目录: {path}")
                    path.mkdir(parents=True, exist_ok=True)
                    logger.info(f"已创建目录: {path}")
                except Exception as e:
                    logger.error(f"Failed to create directory {name} at {path}: {e}")

    @classmethod
    def get_config_path(cls, config_name: str) -> Path:
        """
        获取特定配置文件的路径。
        :param config_name: 配置文件名，例如 'dev.toml', 'config.yaml'
        :return: 配置文件的完整路径
        """
        config_path = cls.CONFIG_DIR / config_name
        if not config_path.exists():
            logger.warning(f"Requested config file {config_name} does not exist at {config_path}.")
        return config_path

    @classmethod
    def list_all_paths(cls) -> dict:
        """
        列出所有路径常量，返回字典形式，方便调试和查看。
        :return: 包含所有路径常量的字典
        """
        return {name: path for name, path in cls.__dict__.items() if isinstance(path, Path)}

    @classmethod
    def dynamic_path(cls, *sub_paths: str) -> Path:
        """
        动态构造路径。
        :param sub_paths: 路径中的子路径
        :return: 动态构建的路径
        """
        return cls.BASE_DIR.joinpath(*sub_paths)


# 使用缓存来保证 PathManager 的实例唯一
@lru_cache(maxsize=None)
def cache_path_manager() -> PathManager:
    """
    返回 PathManager 的单例实例。
    """
    return PathManager()


# 初始化路径管理实例
paths = cache_path_manager()
paths.ensure_directory_exists()

if __name__ == '__main__':
    # 打印所有路径常量
    all_paths = paths.list_all_paths()
    for name, path in all_paths.items():
        print(f"{name}: {path}")

    # 动态获取特定路径
    print(f"Dynamic Path Example: {paths.dynamic_path('src', 'module', 'file.txt')}")
